﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;

namespace FusionDotNet
{
    /// <summary>
    /// Updates a row in a Google Fusion table.
    /// </summary>
    public class UpdateCommand : PostCommand<CommandResult>
    {
        /// <summary>
        /// Construct a UpdateCommand for the row described by <paramref name="rowData"/>
        /// </summary>
        /// <param name="rowData">DataRow describing the row to update.</param>
        /// <remarks>
        /// The DataTable to which the DataRow is attached must have a valid TableName and have a 'rowid' column as well as at least one other column.
        /// </remarks>
        public UpdateCommand(DataRow rowData)
        {
            BuildUpdateString(rowData);
        }

        private void BuildUpdateString(DataRow rowData)
        {
            rowData.Table
                .TableNotNull()
                .TableHasName()
                .TableHasColumns()
                .TableHasRowIdColumn();

            StringBuilder builder = new StringBuilder();
            builder.Append("sql=");
            builder.AppendFormat("UPDATE {0} SET ", rowData.Table.TableName);

            List<string> updateLines = new List<string>(); 
            DataColumn[] columns = new DataColumn[rowData.Table.Columns.Count];
            rowData.Table.Columns.CopyTo(columns, 0);
            var updateColumns = columns.Where(i => i.ColumnName != Constants.FUSION_ROWID).ToArray();

            if (updateColumns.Length == 0)
            {
                throw ExceptionBuilder.BuildException<InvalidOperationException>("rowData must provide at least one column to update.");
            }

            foreach (DataColumn column in updateColumns)
            {
                updateLines.Add(string.Format("{0} = '{1}'", column.ColumnName, rowData[column]));
            }

            builder.Append(string.Join(",", updateLines.ToArray()));

            builder.AppendFormat(" WHERE ROWID = '{0}'", rowData[Constants.FUSION_ROWID]);

            Encoding encoding = GetContentEncoding();
            PostContent = encoding.GetBytes(builder.ToString());
        }

        /// <summary>
        /// Creates a CommandResult based on the results of the command.
        /// </summary>
        /// <param name="reader">StreamReader containing the results of the operation.</param>
        /// <returns><see cref="CommandResult"/></returns>
        internal override CommandResult CreateResult(System.IO.StreamReader reader)
        {           
            string status = reader.ReadLine();
            var result = new CommandResult();
            if (status == Constants.STATUS_OK)
            {
                result.Success= true;
            }
            else
            {
                result.Success = false;
            }
            return result;
        }
    }
}
